// 问题七：实现HTTP服务器
// 本文件实现了一个简单的HTTP服务器，包含两个API端点：
// 1. /api/time - GET请求返回当前时间
// 2. /api/echo - POST请求返回请求体内容
// 同时包含客户端测试代码，用于验证服务器功能

import 'dart:io'; // 提供HTTP服务器和客户端功能
import 'dart:convert'; // 提供JSON编码解码功能

/// 启动HTTP服务器并监听请求
/// 绑定到本地回环地址(127.0.0.1)的8080端口
/// 处理两种路由：/api/time和/api/echo
/// 其他路径返回404 Not Found
/// 异常情况下返回500 Internal Server Error
Future<void> startServer() async {
  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8080);

  print('服务器运行在 http://${server.address.host}:${server.port}');

  await for (final request in server) {
    try {
      switch (request.uri.path) {
        case '/api/time':
          if (request.method == 'GET') {
            handleTimeRequest(request);
          } else {
            request.response
              ..statusCode = HttpStatus.methodNotAllowed
              ..write('Method Not Allowed')
              ..close();
          }
          break;

        case '/api/echo':
          if (request.method == 'POST') {
            await handleEchoRequest(request);
          } else {
            request.response
              ..statusCode = HttpStatus.methodNotAllowed
              ..write('Method Not Allowed')
              ..close();
          }
          break;

        default:
          request.response
            ..statusCode = HttpStatus.notFound
            ..write('404 Not Found')
            ..close();
      }
    } catch (e) {
      print('处理请求时出错: $e');
      request.response
        ..statusCode = HttpStatus.internalServerError
        ..write('Internal Server Error')
        ..close();
    }
  }
}

/// 处理时间请求
/// 返回当前ISO8601格式的时间字符串
/// @param request HTTP请求对象
void handleTimeRequest(HttpRequest request) {
  final now = DateTime.now().toIso8601String();
  request.response
    ..headers.contentType = ContentType.json
    ..write(jsonEncode({'time': now}))
    ..close();
}

/// 处理回显请求
/// 读取请求体内容并原样返回
/// @param request HTTP请求对象
/// @return Future表示异步操作完成
Future<void> handleEchoRequest(HttpRequest request) async {
  final content = await utf8.decoder.bind(request).join();
  request.response
    ..headers.contentType = ContentType.json
    ..write(jsonEncode({'echo': content}))
    ..close();
}

/// 测试客户端
/// 依次测试：
/// 1. 时间接口GET请求
/// 2. 回显接口POST请求
/// 3. 不存在的路径GET请求
Future<void> testClient() async {
  // 测试时间接口
  final timeResponse = await HttpClient().getUrl(
    Uri.parse('http://localhost:8080/api/time'),
  );
  final timeResult = await timeResponse.close();
  final timeJson =
      await jsonDecode(await utf8.decoder.bind(timeResult).join())
          as Map<String, dynamic>;
  print('\n时间接口响应: ${timeJson['time']}');

  // 测试echo接口
  final echoRequest = await HttpClient().postUrl(
    Uri.parse('http://localhost:8080/api/echo'),
  );
  echoRequest.headers.contentType = ContentType.json;
  echoRequest.write(jsonEncode({'message': '测试Dart HTTP客户端'}));
  final echoResponse = await echoRequest.close();
  final echoJson =
      await jsonDecode(await utf8.decoder.bind(echoResponse).join())
          as Map<String, dynamic>;
  print('Echo接口响应: ${echoJson['echo']}');

  // 测试404
  final notFoundResponse = await HttpClient().getUrl(
    Uri.parse('http://localhost:8080/not_found'),
  );
  final notFoundResult = await notFoundResponse.close();
  print('404接口状态码: ${notFoundResult.statusCode}');
}

/// 主函数
/// 1. 启动服务器
/// 2. 等待1秒确保服务器启动
/// 3. 运行客户端测试
/// 4. 保持服务器运行直到手动停止
void main() async {
  // 启动服务器
  print('启动HTTP服务器...');
  final server = startServer();

  // 等待服务器启动
  await Future.delayed(Duration(seconds: 1));

  // 运行客户端测试
  print('\n运行客户端测试...');
  await testClient();

  // 关闭服务器
  print('\n测试完成，按Ctrl+C退出服务器');
  await server;
}
